home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / boot / sunprom / fs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-11-27  |  8.3 KB  |  327 lines

  1. /* fs.c -
  2.  *
  3.  *    General filesystem support.
  4.  *
  5.  * Copyright (C) 1985 Regents of the University of California
  6.  * All rights reserved.
  7.  */
  8.  
  9. #ifdef notdef
  10. static char rcsid[] = "$Header: /sprite/src/boot/sunprom/RCS/fs.c,v 1.11 90/11/27 11:17:26 jhh Exp $ SPRITE (Berkeley)";
  11. #endif not lint
  12.  
  13. #include "sprite.h"
  14. #include "fsBoot.h"
  15. #include "machMon.h"
  16. #include "ofs.h"
  17.  
  18. /*
  19.  * For non-block aligned reads.
  20.  */
  21. char    readBuffer[FS_BLOCK_SIZE];
  22.  
  23. /*
  24.  * For lookup
  25.  */
  26. static char    component[FS_MAX_NAME_LENGTH];
  27.  
  28. /*
  29.  * Forward declarations.
  30.  */
  31. void FsGetFileDesc();
  32. void FsInitFileHandle();
  33.  
  34. /*
  35.  * ----------------------------------------------------------------------------
  36.  *
  37.  * Open --
  38.  *
  39.  *    Open a file.  This does a simple lookup (based on the kernel's
  40.  *    FsLocalLookup) and creates a handle for the file.
  41.  *
  42.  * Results:
  43.  *    SUCCESS or a return code from various sub-operations.
  44.  *
  45.  * Side effects:
  46.  *    Calls malloc
  47.  *
  48.  * ----------------------------------------------------------------------------
  49.  */
  50.  
  51. ReturnStatus
  52. Open(fileName, useFlags, permissions, handlePtrPtr)
  53.     char *fileName;
  54.     int useFlags;
  55.     int permissions;
  56.     Fsio_FileIOHandle     **handlePtrPtr;
  57. {
  58.     register ReturnStatus status;
  59.     Fsio_FileIOHandle *curHandlePtr;
  60.     register char *curCharPtr;
  61.     register char *componentPtr;
  62.     register int index;
  63.  
  64.     curCharPtr = fileName;
  65.     while(*curCharPtr == '/') {
  66.     curCharPtr++;
  67.     }
  68.     curHandlePtr = fsRootHandlePtr;
  69.  
  70.     while (*curCharPtr != '\0') {
  71.     if (curHandlePtr->descPtr->fileType != FS_DIRECTORY) {
  72.         return(FS_NOT_DIRECTORY);
  73.     }
  74.         /*
  75.          * Get the next component.
  76.          */
  77.         index = 0;
  78.     componentPtr = component;
  79.         while (*curCharPtr != '/' && *curCharPtr != '\0') {
  80.             *componentPtr++ = *curCharPtr++;
  81.         }
  82.         *componentPtr = '\0';
  83. #ifndef NO_PRINTF
  84.     Mach_MonPrintf(" %s ", component);
  85. #endif
  86.         /*
  87.          * Skip intermediate and trailing slashes so that *curCharPtr
  88.          * is Null when 'component' has the last component of the name.
  89.          */
  90.         while (*curCharPtr == '/') {
  91.             curCharPtr++;
  92.         }
  93.  
  94.     status = FsFindComponent(fsDomainPtr, curHandlePtr, component,
  95.                           &curHandlePtr);
  96.  
  97.     if (status != SUCCESS) {
  98. #ifndef NO_PRINTF
  99.         Mach_MonPrintf("<%x>\n", status);
  100. #endif
  101.         return(status);
  102.     }
  103.     }
  104.     *handlePtrPtr = curHandlePtr;
  105.     return status;
  106. }
  107.  
  108. /*
  109.  * ----------------------------------------------------------------------------
  110.  *
  111.  * Read --
  112.  *
  113.  *    Read from a file given its handle.
  114.  *
  115.  * Results:
  116.  *    A return status from the read.
  117.  *
  118.  * Side effects:
  119.  *    buffer is loaded with the data read in.
  120.  *    *readCountPtr is updated to reflect the number of bytes read.
  121.  *
  122.  * ----------------------------------------------------------------------------
  123.  */
  124. ReturnStatus
  125. Read(handlePtr, offset, numBytes, buffer, readCountPtr)
  126.     register Fsio_FileIOHandle     *handlePtr;
  127.     int            offset;
  128.     int            numBytes;
  129.     register Address    buffer;
  130.     int            *readCountPtr;
  131. {
  132.     int                firstBlock;
  133.     int                lastBlock;
  134.     int                lastByte;
  135.     BlockIndexInfo        indexInfo;
  136.     register    int        readSize;
  137.     register    int        blockAddr;
  138.     register    int        blockOffset;
  139.     register    int        bufferIndex;
  140.     register     ReturnStatus    status;
  141.     register    int        size;
  142.  
  143.     firstBlock = offset / FS_BLOCK_SIZE; 
  144.     lastByte = offset + numBytes - 1;
  145.     if (lastByte > handlePtr->descPtr->lastByte) {
  146.     lastByte = handlePtr->descPtr->lastByte;
  147.     }
  148.     lastBlock = lastByte / FS_BLOCK_SIZE;
  149.  
  150.     (void)FsGetFirstIndex(handlePtr, firstBlock, &indexInfo);
  151.  
  152.     bufferIndex = 0;
  153.     blockOffset = offset & FS_BLOCK_OFFSET_MASK;
  154. #ifdef SCSI0_BOOT 
  155.     Mach_MonPrintf(" read %d at %d into %x\n", numBytes, offset, buffer);
  156. #endif 
  157.  
  158.     while (indexInfo.blockNum <= lastBlock) {
  159.     if (indexInfo.blockNum < lastBlock) {
  160.         size = FS_BLOCK_SIZE - blockOffset;
  161.         readSize = FS_BLOCK_SIZE;
  162.     } else {
  163.         size = (lastByte & FS_BLOCK_OFFSET_MASK) + 1 - blockOffset;
  164.         readSize = size;
  165.     }
  166.     blockAddr = *indexInfo.blockAddrPtr + 
  167.     ((Ofs_DomainHeader *) fsDomainPtr->clientData)->dataOffset *
  168.         FS_FRAGMENTS_PER_BLOCK;
  169.     if (blockOffset != 0 || size != FS_BLOCK_SIZE) { 
  170.         status = FsDeviceBlockIO(FS_READ, &fsDevice, blockAddr,
  171.                (readSize - 1) / FS_FRAGMENT_SIZE + 1, readBuffer);
  172.         if (status != SUCCESS) {
  173.         goto readError;
  174.         }
  175.         bcopy(&(readBuffer[blockOffset]), &(buffer[bufferIndex]), size);
  176.     } else {
  177.         status = FsDeviceBlockIO(FS_READ, &fsDevice, blockAddr,
  178.             FS_FRAGMENTS_PER_BLOCK, &(buffer[bufferIndex]));
  179.         if (status != SUCCESS) {
  180.         goto readError;
  181.         }
  182.     }
  183.     bufferIndex += size;
  184.     blockOffset = 0;
  185.     FsGetNextIndex(handlePtr, &indexInfo);
  186.     }
  187.  
  188. readError:
  189.  
  190.     *readCountPtr = bufferIndex;
  191.  
  192.     return(status);
  193. }
  194.  
  195. /*
  196.  *----------------------------------------------------------------------
  197.  *
  198.  * FsFindComponent --
  199.  *
  200.  *
  201.  * Results:
  202.  *    None.
  203.  *
  204.  * Side effects:
  205.  *
  206.  *----------------------------------------------------------------------
  207.  */
  208. ReturnStatus
  209. FsFindComponent(domainPtr, curHandlePtr, component, newHandlePtrPtr)
  210.     Fsdm_Domain *domainPtr;
  211.     Fsio_FileIOHandle *curHandlePtr;
  212.     char *component;
  213.     Fsio_FileIOHandle **newHandlePtrPtr;
  214. {
  215.     register ReturnStatus status;
  216.     register int dirOffset;        /* Offset within the directory */
  217.     register int blockOffset;        /* Offset within a directory block */
  218.     register Fslcl_DirEntry *dirEntryPtr;    /* Reference to directory entry */
  219.     int length;                /* Length variable for read call */
  220.     register Fsio_FileIOHandle *handlePtr;
  221.  
  222.     dirOffset = 0;
  223.     do {
  224.     length = FSLCL_DIR_BLOCK_SIZE;
  225.     status = Read(curHandlePtr, dirOffset, length, readBuffer, &length);
  226.     if (status != SUCCESS) {
  227.         return(status);
  228.     }
  229.     if (length == 0) {
  230.         return(FS_FILE_NOT_FOUND);
  231.     }
  232.     dirEntryPtr = (Fslcl_DirEntry *)readBuffer;
  233.     blockOffset = 0;
  234.     while (blockOffset < FSLCL_DIR_BLOCK_SIZE) {
  235.         dirEntryPtr = (Fslcl_DirEntry *)((int)readBuffer + blockOffset);
  236.         if (dirEntryPtr->fileNumber != 0) {
  237.         /*
  238.          * A valid directory record.
  239.          */
  240. #ifndef NO_PRINTF
  241.         Mach_MonPrintf("Found %s\n", dirEntryPtr->fileName);
  242. #endif NO_PRINTF
  243.         if (strcmp(component, dirEntryPtr->fileName) == 0) {
  244.             handlePtr = (Fsio_FileIOHandle *)malloc(sizeof(Fsio_FileIOHandle));
  245.             FsInitFileHandle(domainPtr, dirEntryPtr->fileNumber,
  246.                     handlePtr);
  247.             *newHandlePtrPtr = handlePtr;
  248.             return(SUCCESS);
  249.         }
  250.         }
  251.         blockOffset += dirEntryPtr->recordLength;
  252.     }
  253.     dirOffset += FSLCL_DIR_BLOCK_SIZE;
  254.     } while(TRUE);
  255. }
  256.  
  257. /*
  258.  *----------------------------------------------------------------------
  259.  *
  260.  * FsInitFileHandle --
  261.  *
  262.  *    Initialize a file handle.
  263.  *
  264.  * Results:
  265.  *    None.
  266.  *
  267.  * Side effects:
  268.  *    Fills in the file handle that our caller has already allocated.
  269.  *
  270.  *----------------------------------------------------------------------
  271.  */
  272. void
  273. FsInitFileHandle(domainPtr, fileNumber, handlePtr)
  274.     Fsdm_Domain *domainPtr;
  275.     int fileNumber;
  276.     register Fsio_FileIOHandle *handlePtr;
  277. {
  278.     register Fsdm_FileDescriptor *descPtr;
  279.  
  280.     bzero((Address)handlePtr, sizeof(Fsio_FileIOHandle));
  281.     handlePtr->hdr.fileID.minor = fileNumber;
  282.     descPtr = (Fsdm_FileDescriptor *)malloc(sizeof(Fsdm_FileDescriptor));
  283.     FsGetFileDesc(domainPtr, fileNumber, descPtr);
  284.     handlePtr->descPtr = descPtr;
  285. }
  286.  
  287. /*
  288.  *----------------------------------------------------------------------
  289.  *
  290.  * FsGetFileDesc --
  291.  *
  292.  *    Read in a file descriptor from the disk.
  293.  *
  294.  * Results:
  295.  *    None.
  296.  *
  297.  * Side effects:
  298.  *    Fills in the file descriptor that our caller has already allocated.
  299.  *
  300.  *----------------------------------------------------------------------
  301.  */
  302. void
  303. FsGetFileDesc(domainPtr, fileNumber, descPtr)
  304.     Fsdm_Domain *domainPtr;
  305.     register int fileNumber;
  306.     register Fsdm_FileDescriptor *descPtr;
  307. {
  308.     register Ofs_DomainHeader *headerPtr;
  309.     register int         blockNum;
  310.     register int         offset;
  311.  
  312.     headerPtr = ((Ofs_DomainHeader *) domainPtr->clientData);
  313.     blockNum = headerPtr->fileDescOffset + fileNumber / FSDM_FILE_DESC_PER_BLOCK;
  314.     offset = (fileNumber & (FSDM_FILE_DESC_PER_BLOCK - 1)) *
  315.         FSDM_MAX_FILE_DESC_SIZE;
  316.  
  317.     (void)FsDeviceBlockIO(FS_READ, &fsDevice, 
  318.                blockNum * FS_FRAGMENTS_PER_BLOCK,
  319.                FS_FRAGMENTS_PER_BLOCK, readBuffer);
  320.     bcopy( readBuffer + offset, (char *) descPtr, sizeof(Fsdm_FileDescriptor));
  321. #ifndef NO_PRINTF
  322.     if (descPtr->magic != FS_FD_MAGIC) {
  323.     Mach_MonPrintf("desc %d bad <%x>\n", fileNumber, descPtr->magic);
  324.     }
  325. #endif
  326. }
  327.